package com.example.fileupload;

import com.example.fileupload.entity.FileInfo;
import com.example.fileupload.service.FileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/file")
public class FileController {
    
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);
    
    @Autowired
    private FileService fileService;
    
    @PostMapping("/upload")
    public ResponseEntity<Map<String, Object>> uploadFile(@RequestParam("file") MultipartFile file) {
        logger.info("接收到文件上传请求");
        Map<String, Object> response = new HashMap<>();
        
        try {
            if (file == null) {
                logger.error("上传文件为null");
                response.put("code", 400);
                response.put("message", "文件不能为空");
                response.put("response", null);
                return ResponseEntity.badRequest().body(response);
            }
            
            if (file.isEmpty()) {
                logger.error("上传文件内容为空");
                response.put("code", 400);
                response.put("message", "文件内容不能为空");
                response.put("response", null);
                return ResponseEntity.badRequest().body(response);
            }
            
            logger.info("文件名: {}", file.getOriginalFilename());
            FileInfo savedFile = fileService.saveFile(file);
            
            logger.info("文件上传成功，文件ID: {}", savedFile.getId());
            response.put("code", 200);
            response.put("message", "文件上传成功");
            response.put("response", savedFile);
            
            return ResponseEntity.ok(response);
        } catch (MultipartException e) {
            logger.error("文件上传格式错误: {}", e.getMessage());
            response.put("code", 400);
            response.put("message", "请求必须是multipart/form-data格式，请正确设置Content-Type");
            response.put("response", null);
            return ResponseEntity.badRequest().body(response);
        } catch (IOException e) {
            logger.error("文件上传失败", e);
            response.put("code", 500);
            response.put("message", "系统内部错误: " + e.getMessage());
            response.put("response", null);
            return ResponseEntity.status(500).body(response);
        } catch (Exception e) {
            logger.error("文件上传过程中发生未知错误", e);
            response.put("code", 500);
            response.put("message", "系统内部错误: " + e.getMessage());
            response.put("response", null);
            return ResponseEntity.status(500).body(response);
        }
    }
    
    // 添加异常处理器，专门处理MultipartException
    @ExceptionHandler(MultipartException.class)
    public ResponseEntity<Map<String, Object>> handleMultipartException(MultipartException ex) {
        logger.error("Multipart请求错误: {}", ex.getMessage());
        Map<String, Object> response = new HashMap<>();
        response.put("code", 400);
        response.put("message", "请求必须是multipart/form-data格式，请正确设置Content-Type");
        response.put("response", null);
        return ResponseEntity.badRequest().body(response);
    }
    
    @GetMapping("/list")
    public ResponseEntity<Map<String, Object>> getFiles() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            List<FileInfo> files = fileService.getAllFiles();
            response.put("success", true);
            response.put("files", files);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取文件列表失败: " + e.getMessage());
            return ResponseEntity.status(500).body(response);
        }
    }
    
    @GetMapping("/download/{id}")
    public ResponseEntity<Resource> downloadFile(@PathVariable Long id) {
        logger.info("收到文件下载请求，文件ID: {}", id);
        
        try {
            FileInfo fileInfo = fileService.getFileById(id);
            if (fileInfo == null) {
                logger.warn("文件不存在，ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            logger.info("准备下载文件: {}, 路径: {}, 大小: {} 字节", 
                    fileInfo.getOriginalName(), fileInfo.getFilePath(), fileInfo.getFileSize());
            
            File file = new File(fileInfo.getFilePath());
            if (!file.exists()) {
                logger.error("文件存在于数据库但不存在于磁盘: {}", fileInfo.getFilePath());
                return ResponseEntity.notFound().build();
            }
            
            logger.info("文件存在于磁盘，开始读取文件内容");
            
            try {
                InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
                
                // 确保设置正确的Content-Type
                String contentType = fileInfo.getContentType();
                if (contentType == null || contentType.isEmpty()) {
                    contentType = "application/octet-stream"; // 默认二进制类型
                    logger.info("使用默认Content-Type: {}", contentType);
                }
                
                // 确保文件名正确编码
                String encodedFileName = new String(fileInfo.getOriginalName().getBytes("UTF-8"), "ISO-8859-1");
                
                logger.info("文件读取成功，准备响应下载，文件名: {}", encodedFileName);
                
                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"")
                        .header(HttpHeaders.CONTENT_LENGTH, String.valueOf(file.length()))
                        .header("Access-Control-Expose-Headers", "Content-Disposition") // 允许前端访问Content-Disposition头
                        .body(resource);
            } catch (IOException e) {
                logger.error("读取文件失败: {}", e.getMessage(), e);
                return ResponseEntity.status(500).body(null);
            }
        } catch (Exception e) {
            logger.error("文件下载过程中发生异常: {}", e.getMessage(), e);
            return ResponseEntity.status(500).body(null);
        }
    }
    
    @DeleteMapping("/delete/{id}")
    public ResponseEntity<Map<String, Object>> deleteFile(@PathVariable Long id) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            boolean deleted = fileService.deleteFile(id);
            if (deleted) {
                response.put("success", true);
                response.put("message", "文件删除成功");
            } else {
                response.put("success", false);
                response.put("message", "文件不存在或删除失败");
            }
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "删除文件失败: " + e.getMessage());
            return ResponseEntity.status(500).body(response);
        }
    }
}